package com.itchen.school.controller;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.google.common.collect.Lists;
import com.itchen.school.common.Result.R;
import com.itchen.school.common.base.BaseController;
import com.itchen.school.common.constant.Constants;
import com.itchen.school.common.utils.*;
import com.itchen.school.entities.TbStudent;
import com.itchen.school.service.ITbStudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.List;

@CrossOrigin   //跨域
@RestController
@RequestMapping("/student")
public class TbStudentController extends BaseController {

    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("/getStudentList")
    public R<List<TbStudent>> getStudentList(){
        // 1.在redis中获取数据
        String studentList1 = (String) redisTemplate.opsForValue().get("studentList");
        // 2.判断数据是否存在
        if (StringUtils.isNotEmpty(studentList1)) {
            List<TbStudent> studentList = JSONUtils.parseList(studentList1, TbStudent.class);
            // 2.1存在，直接返回
            return R.successData(studentList);
        }
        // 3.如果不存在，则查询数据库
        List<TbStudent> studentList = ref(ITbStudentService.class).getStudentList();
        if (CollectionUtils.isNotEmpty(studentList)) {
            // 3.1存入redis
            redisTemplate.opsForValue().set("studentList", JSONUtils.serialize(studentList));
        }
        return R.successData(studentList);
    }

    @PostMapping("/saveStudent")
    public R<Object> saveStudent(@RequestBody TbStudent student) {
        // 1.保存数据
        boolean saveFlag = ref(ITbStudentService.class).saveStudent(student);
        // 2.更新缓存
        redisTemplate.delete("studentList");
        return saveFlag ? R.success() : R.error();
    }

    @PostMapping("/getStudentOne/{id}")
    public R<Object> getStudentOne(@PathVariable String id) {
        // 1.在redis中获取数据
        String student = (String) redisTemplate.opsForValue().get(id);
        // 2.判断数据是否存在
        if (StringUtils.isNotEmpty(student)) {
            TbStudent tbStudent = JSONUtils.parse(student, TbStudent.class);
            // 2.1存在，直接返回
            return R.successData(tbStudent);
        }
        // 3.如果没有再查询数据库
        TbStudent studentOne = ref(ITbStudentService.class).getStudentOne(id);
        if (ObjectUtils.isNotEmpty(studentOne)) {
            // 3.1存入redis
            redisTemplate.opsForValue().set(id, JSONUtils.serialize(student));
        }
        return R.successData(studentOne);
    }

    @PostMapping("/editStudent")
    public R<Object> editStudent(@RequestBody TbStudent student) {
        // 1.修改数据
        boolean editFlag = ref(ITbStudentService.class).editStudent(student);
        // 2.更新缓存
        redisTemplate.delete("studentList");
        redisTemplate.delete(student.getId());
        return editFlag ? R.success() : R.error();
    }

    @PostMapping("/deleteStudent")
    public R<Object> deleteStudent(@RequestBody List<String> ids) {
        // 1.删除数据
        boolean deleteFlag = ref(ITbStudentService.class).deleteStudent(ids);
        // 2.更新缓存
        redisTemplate.delete("studentList");
        redisTemplate.delete(ids.get(0));
        return deleteFlag ? R.success() : R.error();
    }

    @PostMapping("/openRecordStatus")
    public R<Object> openRecordStatus(@RequestBody List<String> ids) {
        // 1.修改状态
        boolean openFlag = ref(ITbStudentService.class).ToggleRecordStatus(ids, Constants.DATA_VALID);
        // 2.删除缓存
        redisTemplate.delete("studentList");
        ids.forEach(x-> {
            redisTemplate.delete(x);
        });
        return openFlag ? R.success() : R.error();
    }

    @PostMapping("/closeRecordStatus")
    public R<Object> closeRecordStatus(@RequestBody List<String> ids) {
        // 1.修改状态
        boolean openFlag = ref(ITbStudentService.class).ToggleRecordStatus(ids, Constants.DATA_INVALID);
        // 2.更新缓存
        redisTemplate.delete("studentList");
        ids.forEach(x-> {
            redisTemplate.delete(x);
        });
        return openFlag ? R.success() : R.error();
    }

    @GetMapping("/exportStudentList")
    public void exportStudentList(HttpServletResponse response) {
        // 创建一个数组用于设置表头
        String[] titles = new String[]{"学生学号","学生姓名","学生性别","出生日期","学生年龄","学生宿舍","班级名称","年级名称","学院名称"};
        // 创建一个列表用于设置表格数据
        List<String[]> exportList = Lists.newArrayList();
        // 1.在redis中获取数据
        String studentsRedis = (String) redisTemplate.opsForValue().get("studentList");
        // 2.判断数据是否存在
        if (StringUtils.isNotEmpty(studentsRedis)) {
            List<TbStudent> students = JSONUtils.parseList(studentsRedis, TbStudent.class);
            if (CollectionUtils.isNotEmpty(students)) {
                students.forEach( x-> {
                    String[] row = {
                            x.getNumber(), x.getName(), (x.getSex() == 1 ? "男" : "女"),
                            DateUtils.dateConvertStr(String.valueOf(x.getBirthday()),"yyyy-MM-dd HH:mm"),
                            x.getAge() + "", x.getDormitoryName(), x.getClassName(), x.getGradeName(), x.getCollegeName()
                    };
                    exportList.add(row);
                });
            }
            //调用Excel导出工具类
            ExcelExportUtils.exportExcel(response, exportList, titles, "学生信息表");
            return;
        }
        // 3.如果没有再查询数据库
        List<TbStudent> studentsMySQL = ref(ITbStudentService.class).getStudentList();
        if (CollectionUtils.isNotEmpty(studentsMySQL)) {
            // 3.1存入redis
            redisTemplate.opsForValue().set("studentList", JSONUtils.serialize(studentsMySQL));
            studentsMySQL.forEach( x-> {
                String[] row = {
                        x.getNumber(), x.getName(), (x.getSex() == 1 ? "男" : "女"),
                        DateUtils.dateConvertStr(String.valueOf(x.getBirthday()),"yyyy-MM-dd HH:mm"),
                        x.getAge() + "", x.getDormitoryName(), x.getClassName(), x.getGradeName(), x.getCollegeName()
                };
                exportList.add(row);
            });
        }
        //调用Excel导出工具类
        ExcelExportUtils.exportExcel(response, exportList, titles, "学生信息表");
    }

    @PostMapping("/importStudentList")
    public R<Object> importStudentList(@RequestParam("file") MultipartFile file) {
        File fileTemp = ExcelExportUtils.createFileFromMultipartFile(file);
        String fileName = ref(ITbStudentService.class).importTbStudentList(fileTemp);
        // 判断导入的数据是否成功
        if (StringUtils.isNotEmpty(fileName)) {
            // 返回导入失败原因的文件名
            R<Object> objectR = new R<>();
            objectR.setCode(2004);
            objectR.addMap("failFileName", fileName);
            return objectR;
        } else {
            // 导入成功，更新缓存
            redisTemplate.delete("studentList");
            return R.success();
        }
    }

    @GetMapping("/getExcel/{fileName}")
    public void getExcel(HttpServletResponse response, @PathVariable String fileName) {
        try {
            String dirPath = "." + File.separator+"uploads" + File.separator+"createExcel" + File.separator + fileName;
            ExcelExportUtils.exportFileWeb(response, dirPath, "导入失败原因");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

}
